package org.changs.nav.ui.nav;

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.TextureSupportMapFragment;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.PoiItem;

import org.changs.aplug.interf.OnIntervalClickListener;
import org.changs.aplug.plug.InjectEventBusOnCreate;
import org.changs.nav.R;
import org.changs.nav.databinding.MainMapFragmentBinding;
import org.changs.nav.delegate.MapSwitchDelegate;
import org.changs.nav.delegate.amap.domain.PoiPoint;
import org.changs.nav.delegate.global.AmapNavHelper;
import org.changs.nav.event.PoiItemClickEvent;
import org.changs.nav.event.RouteItemClickEvent;
import org.changs.nav.ui.nav.mapscene.AbstractMapScene;
import org.changs.nav.ui.nav.mapscene.BasicsMapScene;
import org.changs.nav.ui.nav.mapscene.CollectMapScene;
import org.changs.nav.ui.nav.mapscene.PoiListMapScene;
import org.changs.nav.ui.nav.mapscene.RouteListMapScene;
import org.greenrobot.eventbus.Subscribe;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import aplug.data.db.CollectInfoHelper;
import aplug.data.db.mode.CollectInfo;
import dagger.Lazy;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;

/**
 * Created by 惠安 on 2017/11/24.
 */

public class MainMapFragment extends BaseMapFragment implements MapSwitchDelegate, InjectEventBusOnCreate {

    private MainMapFragmentBinding mBinding;
    private AMap mAMap;
    private List<AbstractMapScene> mAbstractMapScene = new ArrayList<>(5);
    private Map<Long, Marker> mCollectMarker = new HashMap<>();
    private MarkerOptions mCollectMarkerOptions;
    private AbstractMapScene mCurrentMapScene;
    @Inject Lazy<AmapNavHelper> mAmapNavHelper;
    @Inject CollectInfoHelper mCollectInfoHelper;
    @Inject BasicsMapScene mBasicsMapScene;
    @Inject CollectMapScene mCollectMapScene;
    @Inject PoiListMapScene mPoiListMapScene;
    @Inject RouteListMapScene mRouteListMapScene;

    @Override
    public View setup(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mBinding = DataBindingUtil.inflate(inflater, R.layout.main_map_fragment, container, false);
        return mBinding.getRoot();
    }


    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mAMap = ((TextureSupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();

        mAMap.getUiSettings().setZoomControlsEnabled(false);
        mAMap.setTrafficEnabled(true);
        mAMap.showBuildings(true);
        mAMap.showMapText(true);
        mAMap.showIndoorMap(false);
        mAMap.setMapType(AMap.MAP_TYPE_NAVI);//导航地图模式

        //初始化基础的地图按钮事件
        mBinding.btnZoomIn.setOnClickListener(v -> getAMap().animateCamera(CameraUpdateFactory.zoomOut()));
        mBinding.btnZoomOut.setOnClickListener(v -> getAMap().animateCamera(CameraUpdateFactory.zoomIn()));
        mBinding.btnRoads.setOnClickListener(v -> {
            getAMap().setTrafficEnabled(!getAMap().isTrafficEnabled());
            mBinding.btnRoads.setImageResource(getAMap().isTrafficEnabled() ?
                    R.mipmap.auto_ic_roads_close : R.mipmap.auto_ic_roads_open);
        });
        mBinding.btn2d3d.setOnClickListener(new OnIntervalClickListener() {
            @Override
            public void intervalOnClick(View v) {
                final MyLocationStyle myLocationStyle = getAMap().getMyLocationStyle();
                if (myLocationStyle.getMyLocationType() != MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER) {
                    myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);
                    mBinding.btn2d3d.setImageResource(R.mipmap.auto_ic_3d_car);
                } else {
                    myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);
                    mBinding.btn2d3d.setImageResource(R.mipmap.auto_ic_2d_car);
                }
                getAMap().setMyLocationStyle(myLocationStyle);
            }
        });
        getAMap().setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
            @Override
            public void onMapLoaded() {
                Timber.d("onMapLoaded() called");
                mBasicsMapScene.gotoMyLocation();
                showCollectMarket();
            }
        });

        createdMapScene(savedInstanceState);
        mCurrentMapScene = mBasicsMapScene;
    }

    /**
     * 添加收藏点到地图
     */
    private void showCollectMarket() {
        mCollectInfoHelper.findAll()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<List<CollectInfo>>() {
                    @Override
                    public void accept(List<CollectInfo> collectInfos) throws Exception {
                        Iterator<CollectInfo> iterator = collectInfos.iterator();
                        while (iterator.hasNext()) {
                            if (!iterator.next().isValid())
                                iterator.remove();
                        }
                        if (collectInfos.size() == 0) return;
                        for (CollectInfo collectInfo : collectInfos) {
                            mCollectMarker.put(collectInfo.getId(), mAMap.addMarker(getCollectMarkerOptions().position(new LatLng(collectInfo.getLat(), collectInfo.getLon()))));
                        }
                    }
                });
    }

    private MarkerOptions getCollectMarkerOptions() {
        if (mCollectMarkerOptions == null) {
            mCollectMarkerOptions = new MarkerOptions()
                    .infoWindowEnable(false)
                    .icon(BitmapDescriptorFactory.fromResource(R.mipmap.search_tip_collected));
        }
        return mCollectMarkerOptions;
    }

    public void addCollectMarket(Long id, LatLng latLng) {
        mCollectMarker.put(id, mAMap.addMarker(getCollectMarkerOptions().position(latLng)));
    }

    public void remoteCollectMarket(Long id) {
        Marker marker = mCollectMarker.remove(id);
        if (marker != null) marker.remove();
    }

    private void createdMapScene(Bundle savedInstanceState) {
        mAbstractMapScene.add(mBasicsMapScene);
        mAbstractMapScene.add(mCollectMapScene);
        mAbstractMapScene.add(mPoiListMapScene);
        mAbstractMapScene.add(mRouteListMapScene);

        for (AbstractMapScene mapScene : mAbstractMapScene) {
            mapScene.onCreated(savedInstanceState);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        for (AbstractMapScene mapScene : mAbstractMapScene) {
            mapScene.onSaveInstanceState(outState);
        }
    }

    private void showSceneRemoveOther(AbstractMapScene show) {
        for (AbstractMapScene scene : mAbstractMapScene) {
            if (scene == show) continue;
            scene.hideScene();
        }
        show.showScene();
        mCurrentMapScene = show;
    }

    /**
     * 基础地图，功能：选中某点。
     */
    public void switch2Basics() {
        showSceneRemoveOther(mBasicsMapScene);
    }

    /**
     * 显示poi多点
     *
     * @param poiItems
     */
    public void switch2PoiList(ArrayList<PoiItem> poiItems) {
        mPoiListMapScene.setPoiItems(poiItems, 0);
        showSceneRemoveOther(mPoiListMapScene);
    }

    /**
     * 显示线路，选中某条
     *
     * @param ints
     */
    public void switch2RouteList(int[] ints) {
        mRouteListMapScene.setRouteInts(ints, 0);
        showSceneRemoveOther(mRouteListMapScene);
    }

    @Override
    public void switch2RouteList(int[] ints, PoiPoint endPoint) {
        mAmapNavHelper.get().prepareNav(endPoint);
        switch2RouteList(ints);
    }


    /**
     * 移至某点，中心点偏移量
     */
    public void switch2CollectPoint(LatLng latLng) {
        mCollectMapScene.setLocation(latLng);
        showSceneRemoveOther(mCollectMapScene);
    }

    @Subscribe
    public void onEvent(PoiItemClickEvent event) {
        mPoiListMapScene.selectPoiItem(event.index);
    }

    @Subscribe
    public void onEvent(RouteItemClickEvent event) {
        mRouteListMapScene.selectRoute(event.index);
    }

    public MainMapFragmentBinding getBinding() {
        return mBinding;
    }

    public AMap getAMap() {
        return mAMap;
    }
}

